package com.ocom.payconfig.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.ocom.common.entity.card.EntityXfAccountInfo;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.entity.typehandler.SignNoHandle;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.utils.StringUtils;
import com.ocom.common.vo.pay.ABCRechargeVo;
import com.ocom.common.vo.pay.UpdateListRechargeVo;
import com.ocom.common.vo.pay.UpdateSubsidyVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.client.XfRecordFeign;
import com.ocom.payconfig.dao.IDaoAccountInfo;
import com.ocom.payconfig.service.SubsidyDataService;
import com.ocom.payconfig.service.XfAccountInfoService;
import com.ocom.payconfig.service.XfRecordProcessService;
import com.ocom.payconfig.vo.GetListRechargeRVo;
import com.ocom.payconfig.vo.GetListRechargeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class XfAccountInfoServiceImpl extends ServiceImpl<IDaoAccountInfo, EntityXfAccountInfo> implements XfAccountInfoService {


    @Autowired
    private IDaoAccountInfo accountInfo;


    @Autowired
    private SubsidyDataService subsidyDataService;

    @Autowired
    private XfRecordProcessService xfRecordProcessService;

    @Autowired
    private XfRecordFeign xfRecordFeign;

    //获取账号信息(getXFAccount)

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public EntityXfAccountInfo GetXFAccount(Long comId, Integer pId,Integer accountState) {
        QueryWrapper<EntityXfAccountInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.eq("p_id",pId);
        if(accountState>=0){
            query.eq("account_state",accountState);
        }
        return this.getOne(query);
    }


    //初始化账号(addXFAccount)
    //行级锁
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Override
    public void AddXFAccount(Long comId, EntityXfAccountInfo entityXfAccountInfo) {
        accountInfo.insert(entityXfAccountInfo);
    }

    // 修改账号信息(updateXFAccount)
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Override
    public void UpdateXFAccount(Long comId, EntityXfAccountInfo entityXfAccountInfo) {
        SignNoHandle signNoHandle =new SignNoHandle();
        entityXfAccountInfo.setSignNo(signNoHandle.encrypt(entityXfAccountInfo.getSignNo(),1l));
        UpdateWrapper<EntityXfAccountInfo> updateWrapper =new UpdateWrapper<>();
        updateWrapper.eq("com_id",entityXfAccountInfo.getComId());
        updateWrapper.eq("p_id",entityXfAccountInfo.getPId());
        updateWrapper.set("update_time",new Date());
        if(entityXfAccountInfo.getDeptId()!=null){
            updateWrapper.set("dept_id",entityXfAccountInfo.getDeptId());
        }
        if(entityXfAccountInfo.getAccountState()!=null){
            updateWrapper.set("account_state",entityXfAccountInfo.getAccountState());
        }
        if(entityXfAccountInfo.getAccTypeId()!=null) {
            updateWrapper.set("acc_type_id", entityXfAccountInfo.getAccTypeId());
        }
        updateWrapper.set("end_date",entityXfAccountInfo.getEndDate());
        this.update(updateWrapper);
//        accountInfo.updateById(entityXfAccountInfo);
    }

    //判断账户号唯一
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public EntityXfAccountInfo selectAccountNo(Long comId, String accountNo) {
        QueryWrapper<EntityXfAccountInfo> query = Wrappers.query();
        query.eq("account_no",accountNo);
        return accountInfo.selectOne(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<GetListRechargeRVo> GetListRecharge(Long comId, GetListRechargeVo getListRechargeVo) {
        PageHelper.startPage(getListRechargeVo.getPage(),getListRechargeVo.getSize());
        List<Integer> deptIdsList = new ArrayList<>();
        if (getListRechargeVo.getDeptIds() != null && !getListRechargeVo.getDeptIds().isEmpty()){
            String[] deptIdsArr = getListRechargeVo.getDeptIds().split(",");
            for (String deptId: deptIdsArr) {
                if (deptId.isEmpty()){
                    continue;
                }
                deptIdsList.add(Integer.valueOf(deptId));
            }
        }
        return accountInfo.GetListRecharge(getListRechargeVo.getComId(),deptIdsList,getListRechargeVo.getPCode(),
                getListRechargeVo.getPName(),getListRechargeVo.getCardNo(),getListRechargeVo.getAccountNo(),
                getListRechargeVo.getAccTypeId(),getListRechargeVo.getPId());
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @Override
    public Boolean UpdateListRecharge(Long comId, UpdateListRechargeVo updateListRechargeVo) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper = Wrappers.update();
        updateWrapper.eq("com_id",updateListRechargeVo.getComId());
        updateWrapper.eq("account_state",0);

        if(updateListRechargeVo.getPId()!=null && updateListRechargeVo.getPId()>0l){
            updateWrapper.eq("p_id",updateListRechargeVo.getPId());
        }else{
            throw new RuntimeException("人员id不能为空");
        }

        // account_recharge_money=account_recharge_money+@rechargeMoney
//        EntityXfAccountInfo entityXfAccountInfo = new EntityXfAccountInfo();
//        if (StringUtils.isNotNull(updateListRechargeVo.getAccountRechargeMoney())||StringUtils.isNotNull(updateListRechargeVo.getRechargeMoney())){
//            entityXfAccountInfo.setAccountRechargeMoney(updateListRechargeVo.getAccountRechargeMoney()+updateListRechargeVo.getRechargeMoney());
//        }else{
//            throw new RuntimeException("金额不能为空");
//        }
//        log.info("充值更新数据,{{}}",entityXfAccountInfo);
//        return accountInfo.update(entityXfAccountInfo,query);
        if (StringUtils.isNull(updateListRechargeVo.getRechargeMoney()) || updateListRechargeVo.getRechargeMoney() == 0){
            throw new RuntimeException("金额不能为空");
        }
        updateWrapper.setSql(" account_recharge_money = account_recharge_money + "+updateListRechargeVo.getRechargeMoney());
        return this.update(updateWrapper);

    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @Override
    public Boolean  updateSubsidy(Long comId, UpdateSubsidyVo updateSubsidyVo) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper = Wrappers.update();
        updateWrapper.eq("com_id",updateSubsidyVo.getComId());
        updateWrapper.eq("account_state",0);
        if(updateSubsidyVo.getPId()!=null && updateSubsidyVo.getPId()>0l){
            updateWrapper.eq("p_id",updateSubsidyVo.getPId());
        }else{
            throw new RuntimeException("人员id不能为空");
        }

        if (StringUtils.isNull(updateSubsidyVo.getRechargeMoney()) || updateSubsidyVo.getRechargeMoney() == 0){
            throw new RuntimeException("金额不能为空");
        }
        updateWrapper.setSql(" account_subsidy_money = account_subsidy_money + " + updateSubsidyVo.getRechargeMoney());
        return this.update(updateWrapper);

    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public void updateAccountTransactional(Long companyId, Integer id, EntityXfRecordProcess entityXfRecordProcess, EntityXfRecordProcess updateXfRecordProcess) {


        //修改金额
        UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
        Boolean setf = false ;
        if (entityXfRecordProcess.getChargeMoney() != null && entityXfRecordProcess.getChargeMoney()!=0){
            updateWrapper.setSql("account_recharge_money = account_recharge_money + "+ entityXfRecordProcess.getChargeMoney());
            setf = true ;
        }
        if (entityXfRecordProcess.getSubMoney() != null && entityXfRecordProcess.getSubMoney()!=0){
            updateWrapper.setSql("account_subsidy_money = account_subsidy_money + "+ entityXfRecordProcess.getSubMoney());
            setf = true ;
        }
        if(!setf)   throw new RuntimeException("金额异常");
        updateWrapper.eq("id",id);
        updateWrapper.eq("account_state",0);
        if(entityXfRecordProcess.getConsState()==null || (entityXfRecordProcess.getConsState()!=10 && entityXfRecordProcess.getConsState()!=12)){
            updateWrapper.last("and 0 <= (account_recharge_money + " + entityXfRecordProcess.getChargeMoney() + ") and 0 <= (account_subsidy_money + " + entityXfRecordProcess.getSubMoney() + ")");
        }

        if (!this.update(updateWrapper)){
            log.error("修改金额失败!订单号：{{}}", entityXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改金额失败");
        }


        if (xfRecordProcessService.updateEntityXfRecord(companyId,updateXfRecordProcess)<=0){
            log.error("修改记录失败!订单号：{{}}", entityXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改记录失败");
        }

    }

    @Override
    public Boolean sign(Long companyId, Long pId, Integer signType, String signNo) {
        SignNoHandle signNoHandle =new SignNoHandle();
        UpdateWrapper<EntityXfAccountInfo> updateWrapper =Wrappers.update();
        updateWrapper.eq("com_id",companyId);
        updateWrapper.eq("p_id",pId);
        updateWrapper.set("sign_type",signType);
        updateWrapper.set("sign_no",signNoHandle.encrypt(signNo,1l));
        return this.update(updateWrapper);
    }

    @Override
    public Boolean abcRecharge(Long comId, ABCRechargeVo updateListRechargeVo) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper = Wrappers.update();
        updateWrapper.eq("com_id",updateListRechargeVo.getComId());
        updateWrapper.eq("account_state",0);
        if(updateListRechargeVo.getPId()!=null && updateListRechargeVo.getPId()>0l){
            updateWrapper.eq("p_id",updateListRechargeVo.getPId());
        }else{
            throw new RuntimeException("人员id不能为空");
        }

        if (StringUtils.isNull(updateListRechargeVo.getRechargeMoney()) || updateListRechargeVo.getRechargeMoney() == 0){
            throw new RuntimeException("金额不能为空");
        }
        updateWrapper.setSql(" account_recharge_money = account_recharge_money + "+updateListRechargeVo.getRechargeMoney());
        return this.update(updateWrapper);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityXfAccountInfo> selectAccountList(Long comId) {
        QueryWrapper<EntityXfAccountInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.eq("account_state",0);
        query.and(wrapper -> wrapper.ne("account_recharge_money",0).or().ne("account_subsidy_money",0));
        return accountInfo.selectList(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public EntityXfAccountInfo getAccount(Long comId, Integer pId) {
        QueryWrapper<EntityXfAccountInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.eq("p_id",pId);
        query.eq("account_state",0);
        query.orderByDesc("id");
        query.last("limit 1");
        return accountInfo.selectOne(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @Override
    public Boolean updatesubsid(Long comId, Integer planId, Integer completeMoney, Long clearMoney, Date date, Integer id) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
        Long money=completeMoney-clearMoney;
        updateWrapper.setSql("account_subsidy_money =account_subsidy_money +"+money);
        updateWrapper.set("update_time",date);
        updateWrapper.eq("id",id);
        updateWrapper.eq("account_state",0);
        boolean bXfAccountInfo=this.update(updateWrapper);
        if (bXfAccountInfo){
            Boolean bsubsidy=subsidyDataService.updateSubsidy(comId,planId,completeMoney,clearMoney,date);
            if (bsubsidy){
                return true;
            }else {
                throw new RuntimeException();
            }
        }else {
            return bXfAccountInfo;
        }
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityXfAccountInfo> selectAccountInfos(Long companyId, Date endDate) {
        if (endDate == null) {
            endDate = new Date();
        }
        QueryWrapper<EntityXfAccountInfo> queryWrapper = Wrappers.query();
        queryWrapper.isNotNull("end_date").ne("end_date","")
                .le("end_date", endDate).eq("account_state",0)
                .orderByAsc("end_date")
                .last("LIMIT  300 ");
        return accountInfo.selectList(queryWrapper);
    }


    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityXfAccountInfo> selectAccountInfosNotice(Long companyId, List<Long> comIds,  Date endDate) {
        if (endDate == null) {
            endDate = new Date();
        }
        QueryWrapper<EntityXfAccountInfo> queryWrapper = Wrappers.query();
        queryWrapper.in("com_id",comIds);
        queryWrapper.isNotNull("end_date").ne("end_date","")
                .eq("end_date", endDate).eq("account_state",0)
                .last("LIMIT  300 ");
        return accountInfo.selectList(queryWrapper);
    }
}
